<?php
/*
 * @Author: 1086 cchcc@qq.com
 * @Date: 2024-04-22 10:38:36
 * @LastEditors: 1086 cchcc@qq.com
 * @LastEditTime: 2024-05-17 09:39:12
 * @FilePath: \erp\api\php\app\pos_v1\controller\SellPosPAY.php
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

declare(strict_types=1);
namespace app\pos_v1\controller;

use think\facade\Db; //门面模式
use app\pos_v1\model\SellPosPAY as mysql; //导入模型
// 前台收银-支查退款
class SellPosPAY
{

    // HTTP请求
    function curl_HTTP($url, $header, $pos_db)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);  // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0); //如果想把一个头包含在输出中，设置这个选项为一个非零值。
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //如果成功只将结果返回，不自动输出任何内容。
        curl_setopt($ch, CURLOPT_POST, 1); //设置为POST方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $pos_db); //POST数据
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLINFO_HEADER_OUT, 1); //启用时追踪句柄的请求字符串。
        $response = curl_exec($ch);
        //dump(curl_error($ch));  //查看报错信息
        // 写文件
        // file_put_contents("ajs/web_api_" . date("Y-m-d_H-i-s", time()) . ".json", $response . "\n", FILE_APPEND);
        curl_close($ch);
        return $response;
    }

    // 现金支付单-处理程序
    private function fu_Pay_cash($data)
    {
        // 币种检测
        // 禁止币种/币种重复的数据修改:状态-金额-预删除等字段
        $data_detection = [
            "yes" => [], //许可币种
            "no" => [], //禁止币种
            "repeat" => ["yes" => [], "no" => []], //重复币种
            "help" => [
                "name" => "本参数说明:支付币种检测-检测数据库内已出现的异常数据-",
                "yes" => "许可币种",
                "no" => "禁止币种",
                "repeat" => "重复出现的许可/禁止币种",
            ],
        ];
        // 数组升序
        function sortByKey($array, $key)
        {
            usort($array, function ($a, $b) use ($key) {
                return $a[$key] <=> $b[$key];
            });
            return $array;
        }
        $data = sortByKey($data, "id"); // 按 "id" 键的值升序排序
        foreach ($data as $rs) {
            $rs2 = null;
            $rs2 = com_currency($rs["pay_currency"]);
            if ($rs2["val"] == null) {
                array_push($data_detection["no"], $rs2["key"]);
                // 更改-禁止币种-数据
                mysql::where([
                    "order_dbid" => $rs["order_dbid"],
                    "client_sn" => $rs["client_sn"],
                    "payway" => "9",
                    "id" => $rs["id"]
                ])->data([
                            "x_del" => 1, //预删除
                            "state" => "ES", //单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
                            "pay_currency_name" => "币种不支持", //支付币种_名称
                            "total_amount" => 0,
                            "net_amount" => 0,
                        ])->update();
            } else {
                array_push($data_detection["yes"], $rs2["key"]);
            }
        }
        // 数组中值出现的次数
        $val_yes = array_count_values($data_detection["yes"]);
        $val_no = array_count_values($data_detection["no"]);
        // 找出出现超过一次的值
        $dup_yes = array_filter($val_yes, function ($count) {
            return $count > 1;
        });
        $dup_no = array_filter($val_no, function ($count) {
            return $count > 1;
        });
        // 输出重复值的数组
        $data_detection["repeat"]["yes"] = array_keys($dup_yes);
        $data_detection["repeat"]["no"] = array_keys($dup_no);
        $repeat_db = []; //重复币种的数据
        for ($i = 0; $i < count($data_detection["repeat"]["yes"]); $i++) {
            foreach ($data as $rs) {
                if ($rs["pay_currency"] == $data_detection["repeat"]["yes"][$i]) {
                    array_push($repeat_db, $rs);
                }
            }
        }
        // 更改-重复币种-数据
        for ($i = 0; $i < count($repeat_db); $i++) {
            if ($i > 0) {
                // 更改-重复币种-数据
                mysql::where([
                    "order_dbid" => $repeat_db[$i]["order_dbid"],
                    "client_sn" => $repeat_db[$i]["client_sn"],
                    "payway" => "9",
                    "id" => $repeat_db[$i]["id"]
                ])->data([
                            "x_del" => 1, //预删除
                            "state" => "ES", //单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
                            "pay_currency_name" => "支付币种重复", //支付币种_名称
                            "total_amount" => 0,
                            "net_amount" => 0,
                        ])->update();
            }
        }
        $apidb = ["code" => 200, "msg" => "现金支付单同步处理完毕[131-fu_Pay_online]", "query" => request()->param(), "db" => $data_detection];
        return $apidb;
    }

    // 线上支付单-处理程序
    private function fu_Pay_online($data)
    {
        // 查询接口
        $url = "http://127.0.0.1:81/POS_V1/PaySqb/pos_query";
        // 请求头
        $header = ["Format:json", "charset=utf-8", "Content-Type: application/json", "Authorization:sn"];
        $api_array2 = [];


        // 遍历数据集-线上支付单
        foreach ($data as $rs) {
            // Pay请求数据包
            // sn与client_sn不能同时为空，优先按照sn查找订单，如果没有，再按照client_sn查询
            $pay_db = [
                "pay_sn" => $rs["pay_sn"], //第三方支付系统返回的唯一单号
                "client_sn" => $rs["client_sn"], //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
            ];


            // PAY远程HTTP
            $pay_api_notify = $this->curl_HTTP($url, $header, json_encode($pay_db));

            if (!$pay_api_notify) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构异常[142-fu_Pay_online]", "query" => request()->param(), "db" => []];
                return $apidb;
            }
            $api_array = json_decode($pay_api_notify, true); //转数组

            if (!is_array($api_array)) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构转数组异常[159-api_array]", "query" => request()->param(), "db" => []];
                return $apidb;
            }
            if ($api_array["code"] != 200) {
                $apidb = ["code" => 201, "msg" => "一级接口异常[162-fu_Pay_online]", "query" => request()->param(), "db" => $api_array];
                return $apidb;
            }
            if ($api_array["pay_db"]["result_code"] != "200") {
                $apidb = ["code" => 201, "msg" => "二级支付接口sqb异常[167-fu_Pay_online]", "query" => request()->param(), "db" => $api_array["pay_db"]];
                return $apidb;
            }
            $total_amount = 0; //原始交易原始交易实收金额
            $net_amount = 0; //计算属性-在帐金额-实收金额减退款金额
            $xdel = 0; //删除数据,1是0否
            $x_del = 0; //预删除1是0否
            if (isset($api_array["pay_db"]["biz_response"]["data"]["sn"])) {
                $xdel = 0; //删除数据,1是0否
                $x_del = 0; //预删除1是0否
                if ($api_array["pay_db"]["biz_response"]["data"]["sn"] == $rs["pay_sn"]) {
                    // 订单存在
                    // https://doc.shouqianba.com/zh-cn/api/annex/resultCode.html#resultCode_order_status
                    // 订单状态列表
                    // CREATED	订单已创建/支付中
                    // PAID	订单支付成功
                    // PAY_CANCELED	支付失败并且已经成功充正
                    // PAY_ERROR	支付异常，不确定是否已经成功充正,请联系收钱吧客服确认是否支付成功
                    // REFUNDED	已成功全额退款
                    // PARTIAL_REFUNDED	已成功部分退款
                    // REFUND_INPROGRESS	退款进行中
                    // REFUND_ERROR	退款异常并且不确定第三方支付通道的最终退款状态
                    // CANCELED	客户端发起的撤单已成功
                    // CANCEL_ERROR	客户端发起的撤单异常并且不确定第三方支付通道的最终状态
                    // CANCEL_INPROGRESS	撤单进行中
                    // INVALID_STATUS_CODE	无效的状态码
                    if ($api_array["pay_db"]["biz_response"]["data"]["order_status"] == "PAID") {
                        $state = "A";
                    } else if ($api_array["pay_db"]["biz_response"]["data"]["order_status"] == "REFUND_INPROGRESS") {
                        $state = "B3";
                    } else if ($api_array["pay_db"]["biz_response"]["data"]["order_status"] == "REFUNDED") {
                        $state = "B1";
                    } else if ($api_array["pay_db"]["biz_response"]["data"]["order_status"] == "PARTIAL_REFUNDED") {
                        $state = "B2";
                    } else {
                        // 其它状态
                        $state = "ES";
                        // $xdel = 1; //删除数据,1是0否
                        $x_del = 1; //预删除1是0否
                    }
                    $total_amount = $api_array["pay_db"]["biz_response"]["data"]["total_amount"]; //原始交易原始交易实收金额
                    $net_amount = $api_array["pay_db"]["biz_response"]["data"]["net_amount"]; //计算属性-在帐金额-实收金额减退款金额
                    $rs_payway = $api_array["pay_db"]["biz_response"]["data"]["payway"]; //支付方式
                    $rs_payway_name = $api_array["pay_db"]["biz_response"]["data"]["payway_name"]; //支付方式名称
                    if ($rs_payway == "1") {
                        $pay_currency = "ZFBPAY";//支付币种
                        // $pay_currency_name = "支付宝";
                    } else if ($rs_payway == "3") {
                        $pay_currency = "WXPAY";
                        // $pay_currency_name = "微信";
                    } else if ($rs_payway == "4") {
                        $pay_currency = "BDPAY";
                        // $pay_currency_name = "百度钱包";
                    } else if ($rs_payway == "5") {
                        $pay_currency = "JDPAY";
                        // $pay_currency_name = "京东钱包";
                    } else if ($rs_payway == "6") {
                        $pay_currency = "QQPAY";
                        // $pay_currency_name = "QQ钱包";
                    } else {
                        $pay_currency = "B1"; //支付币种_A1其它现金_B1其它电子支付_RMB人民币HKD港币USD美元_WXPAY微信ZFBPAY支付宝BDPAY百度钱包JDPAY京东钱包QQPAY_QQ钱包
                        // $pay_currency_name = $rs_payway_name; //支付币种_名称
                    }
                    // 清空
                    $rs_payway = null;
                    $rs_payway_name = null;
                } else {
                    $state = "ES";
                    $apidb = ["code" => 201, "msg" => "单号和本地不相符[233-fu_Pay_online]", "query" => request()->param(), "db" => []];
                    return $apidb;
                }
            } else {
                $state = "ES";
                $apidb = ["code" => 201, "msg" => "单号不存在[238-fu_Pay_online]", "query" => request()->param(), "db" => []];
                return $apidb;
                // $xdel = 1; //删除数据,1是0否
            }
            // 更新订单字段
            // $xdel = 1; //删除数据,1是0否
            if ($xdel == 1) {
                // 单号不存在// 删除数据
                Db::table("pos__p_sell_order_pay")->where([
                    "client_sn" => $rs["client_sn"],
                    "pay_sn" => $rs["pay_sn"]
                ])->delete();
            } else {
                // 支付币种
                $pay_currency = strtoupper($pay_currency); //转为大写
                $pay_currency_is = com_currency($pay_currency);



                if ($pay_currency_is["val"] == null) {
                    $apidb = ["code" => 201, "msg" => "支付币种不支持", "query" => request()->param(), "db" => $pay_currency_is];
                    return (json($apidb));
                }


                // 更新数据
                Db::name("pos__p_sell_order_pay")->where([
                    "client_sn" => $rs["client_sn"],
                    "pay_sn" => $rs["pay_sn"]
                ])->data([
                            "pay_api_notify_query" => $pay_api_notify, //支付接口回调-查询回调
                            "total_amount" => $total_amount / 100, //原始交易实收金额
                            "net_amount" => $net_amount / 100, //计算属性-在帐金额-实收金额减退款金额"
                            "pay_currency" => $pay_currency, //支付币种
                            "pay_currency_name" => $pay_currency_is["val"]["name"], //支付币种_名称
                            "pay_currency_ico" => $pay_currency_is["val"]["ico"], //支付币种_图标
                            "state" => $state, //单据状态
                            "x_del" => $x_del, //预删除1是0否
                            "time_up" => time(), //更新时间
                        ])->update();
            }
            array_push($api_array2, $api_array);
            // usleep(1000000); //暂停1秒钟
        }
        $apidb = ["code" => 200, "msg" => "在线支付单同步处理完毕[271-fu_Pay_online]", "query" => request()->param(), "db" => $api_array2];
        return $apidb;
    }

    // POS销售-支付订单列表-查询-并更新数据库
    public function Query($is_query = false, $dbid = null, $client_sn = null)
    {
        $query = request()->param(); //请求参数
        // $is_interior = false;//是否函数内部请求方式false否true是
        if ($is_query == true) {
            if (is_null($dbid) || is_null($client_sn)) {
                $apidb = ["code" => 201, "time" => time(), "msg" => "参数异常2-dbid/client_sn",];
                return (json($apidb));
            } else {
                $query["dbid"] = $dbid;
                $query["client_sn"] = $client_sn;
            }
        } else {
            // 请求方式验证
            if (!request()->isPost()) {
                $apidb = ["code" => 201, "time" => time(), "msg" => "请求有误-不是Post方式!",];
                return json($apidb);
            }
        }
        $validate = new \app\pos_v1\validate\SellPosPAY_Query; //验证规则
        if (!$validate->check($query)) {
            // 验证不过关提示
            $apidb = ["code" => 201, "msg" => "参数异常-" . $validate->getError(), "query" => $query,];
            return json($apidb);
        }
        // 销售订单
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();
        if ($order_db == null) {
            // 数据集为空
            $apidb = ["code" => 201, "time" => time(), "msg" => "销售单不存在", "query" => request()->param(),];
            return (json($apidb));
        }
        if (!empty($query["client_sn"])) {
            // 按支付单号查自己本单
            $pay_db = mysql::where(["order_dbid" => $order_db["dbid"], "client_sn" => $query["client_sn"],])->select();
        } else {
            // 按销售单号查所有支付单
            $pay_db = mysql::where(["order_dbid" => $order_db["dbid"]])->select();
        }


        $pay_db = $pay_db->toArray();
        if ($pay_db == []) {
            $apidb = ["code" => 201, "time" => time(), "msg" => "没有支付订单", "query" => request()->param(), "db" => $pay_db];
            return (json($apidb));
        }
        $pay_cash_db = []; //现金支付单
        $pay_online_db = []; //线上支付单
        // 遍历数据集
        foreach ($pay_db as $rs) {
            if ($rs["payway"] == 8) {
                // 线上支付单
                array_push($pay_online_db, $rs);
            } else if ($rs["payway"] == 9) {
                // 现金支付单
                array_push($pay_cash_db, $rs);
            } else {
                $apidb = ["code" => 201, "time" => time(), "msg" => "支付币种-参数异常", "query" => request()->param(),];
                return (json($apidb));
            }
        }
        // 现金币种检验数据
        $cash = $this->fu_Pay_cash($pay_cash_db);
        // 线上支付单-处理
        $online = $this->fu_Pay_online($pay_online_db);

        // 现金/上支付单处理结果
        $verify = [
            "name" => "现金/线上支付单处理结果",
            "cash" => $cash,
            "online" => $online,
        ];

        if (!empty($query["client_sn"])) {
            $is_client_sn = true;//查自己本单_true是false否
            // 按支付单号查自己本单
            $pay_li = mysql::where(["order_dbid" => $order_db["dbid"], "client_sn" => $query["client_sn"],])->select();
        } else {
            $is_client_sn = false;//查自己本单_true是false否
            // 按销售单号查所有支付单
            $pay_li = mysql::where(["order_dbid" => $order_db["dbid"]])->select();
        }
        // 设置需要附加的输出属性
        $pay_li->append([
            "state_2",//单据状态_中文
        ]);
        // 单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
        $pay_li->withAttr("state_2", function ($value, $data) {
            $res = ["ES" => "异常状态", "A" => "支付成功", "B1" => "全额退款", "B2" => "部分退款", "B3" => "退款进行中", null => "", "" => ""];
            return $res[$data["state"]];
        });

        //查自己本单_true是false否
        if ($is_client_sn) {
            //设置需要输出的属性
            $pay_li->visible([
                "id",
                "client_sn",//流水单号_内唯一
                "order_dbid",//对应订单数据编号
                "pay_sn",//第三方支付系统返回的唯一单号-保密
                "payway",//支付方式_9现金8线上支付
                "state",//单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
                "total_amount",//计算属性-原始交易实收金额
                "net_amount",//计算属性-在帐金额-实收金额减退款金额
                "pay_currency",//支付币种-A1其它现金_B1其它电子支付-RMB人民币HKD港币USD美元_WXPAY微信ZFBPAY支付宝BDPAY百度钱包JDPAY京东钱包QQPAY_QQ钱包
                "pay_currency_name",//支付币种_名称
                "pay_currency_ico",//支付币种_图标
                "time_new",//计算属性-创建时间
                "time_up",//计算属性-更新时间
                "x_del",//预删除1是0否
                "pay_api_notify_query",//支付接口回调-查询回调
                "pay_db",//商家扫用户支付接口回调
                "exchange_rate",//汇率
                "remark",//备注
            ]);
            $is_client_sn_db = $pay_li;//查单条信息时
        } else {
            $is_client_sn_db = [];

        }

        $pay_li_length = count($pay_li);
        $pay_li_db = [
            "order_count" => $pay_li_length, //单据长度
            "pay_cash" => [], //现金支付单
            "pay_online" => [], //线上支付单
        ];
        for ($i = 0; $i < $pay_li_length; $i++) {
            $rs = [
                "id" => $pay_li[$i]["id"],
                "order_dbid" => $pay_li[$i]["order_dbid"], //商户系统销售单号-内唯一
                "client_sn" => $pay_li[$i]["client_sn"], //商户系统支付单号-内唯一
                // "pay_sn" => $pay_li[$i]["pay_sn"],//第三方支付系统单号-唯一
                "payway" => $pay_li[$i]["payway"], //支付方式-9现金8聚合支付
                "state" => $pay_li[$i]["state"], //单据状态-A支付成功B1全额退款B2部分退款B3退款进行中
                "state_2" => $pay_li[$i]["state_2"], //单据状态_中文
                "pay_currency" => $pay_li[$i]["pay_currency"], //支付币种
                "pay_currency_name" => $pay_li[$i]["pay_currency_name"], //支付币种_名称
                "pay_currency_ico" => $pay_li[$i]["pay_currency_ico"], //支付币种_图标
                "total_amount" => $pay_li[$i]["total_amount"] * 1, //计算属性-原始交易实收金额
                "net_amount" => $pay_li[$i]["net_amount"] * 1, //计算属性-计算属性-在帐金额-实收金额减退款金额
                // "pay_api_notify_query" => $pay_li[$i]["pay_api_notify_query"],//支付接口回调-查询回调
                // "pay_db" => $pay_li[$i]["pay_db"],//商家扫用户支付接口回调
                "time_new" => $pay_li[$i]["time_new"], //计算属性-创建时间
                "time_up" => $pay_li[$i]["time_up"], //计算属性-更新时间
            ];
            if ($pay_li[$i]["payway"] == "9") {
                // 现金支付单
                array_push($pay_li_db["pay_cash"], $rs);
            } else if ($pay_li[$i]["payway"] == "8") {
                // 线上支付单
                array_push($pay_li_db["pay_online"], $rs);
            } else {
            }
        }
        // 销售订单
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();
        // API接口信息
        $help = [
            "name" => "获取支付单信息",
            "notice" => "部分字段可能不返回，没用到的字段不要预设，部分描述文字可能有错误。",
            "txt" => "client_sn参数存在时-按单条支付单查询-否则查询当下销售单关联的全部支付单。",
            "code" => "错误代码",
            "time" => "接口运行时间",
            "msg" => "状态信息",
            "query=接口请求参数包" => [
                "dbid" => "销售单-单号-必填",
                "client_sn" => "销售单-关联的支付单号"
            ],
            "db=接口回调核心数据包" => [
                "order_count" => "单据长度",
                "pay_cash" => "现金支付单-数组数据包",
                "pay_online" => "线上支付单-数组数据包",
                "verify" => "现金/上支付单处理结果-开发人员处理异常时专用",
                "order_db=销售单数据" => [],
                "pay_db=支付单数据" => [
                    "order_dbid" => "商户系统销售单号-内唯一",
                    "client_sn" => "商户系统支付单号-内唯一",
                    // "pay_sn" => "第三方支付系统单号-唯一",
                    "payway" => "支付方式-9现金8聚合支付",
                    "state" => "单据状态-A支付成功B1全额退款B2部分退款B3退款进行中",
                    "pay_currency" => "支付币种_A1其它现金_B1其它电子支付_RMB人民币HKD港币USD美元_WXPAY微信ZFBPAY支付宝BDPAY百度钱包JDPAY京东钱包QQPAY_QQ钱包",
                    "pay_currency_name" => "支付币种_名称",
                    "total_amount" => "计算属性-原始交易实收金额",
                    "net_amount" => "计算属性-计算属性-在帐金额-实收金额减退款金额",
                    // "pay_api_notify_query" => "支付接口回调-查询回调",
                    // "pay_db" => "商家扫用户支付接口回调",
                    "time_new" => "计算属性-创建时间",
                    "time_up" => "计算属性-更新时间",
                ]
            ]
        ];


        $apidb = [
            "code" => 200,
            "time" => time(),
            "msg" => "获取支付单信息-成功", //状态信息
            "query" => $query, //请求参数
            "is_client_sn" => $is_client_sn_db,//查单条信息时返回本单详细信息_查列表时返回空
            // "order_db" => $order_db,//销售单数据
            // "pay_online" => $pay_online_db, //线上支付单数据
            // "pay_cash" => $pay_cash_db, //现金支付单数据
            // "pay_api_notify_array2" => $api_array2, //聚合支付API回调
            "db" => [
                "order_db" => $order_db, //销售单数据
                "pay_db" => $pay_li_db, //支付单数据
                "verify" => $verify, //现金/上支付单处理结果
            ],
            "API接口信息" => $help, //API信息
        ];
        return (json($apidb));
    }

    /** POS销售-发起支付 */
    public function Pay()
    {
        $query = request()->param(); //请求参数
        // 请求方式验证
        if (!request()->isPost()) {
            return json(["code" => 201, "time" => time(), "msg" => "不是POST方式!",]);
        }

        if (is_numeric($query["total_amount"]) == false) {
            return json(["code" => 201, "time" => time(), "msg" => "金额必须为数字", "query" => $query,]);
        }
        $query["total_amount"] = (float) $query["total_amount"];

        $validate = new \app\pos_v1\validate\SellPosPAY_Pay; //验证规则
        if (!$validate->check($query)) {
            // 验证不过关提示
            $apidb = ["code" => 201, "time" => time(), "msg" => "[参数异常]" . $validate->getError(), "query" => $query,];
            return json($apidb);
        }


        /** 单头 */
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();

        $order_db["total_price"] = (float) $order_db["total_price"];//整单总价_原始价
        $order_db["total_price_new"] = (float) $order_db["total_price_new"];//整单总价_实收价


        // 数据集为空
        if ($order_db == null) {
            return (json(["code" => 201, "time" => time(), "msg" => "销售单不存在", "query" => $query,]));
        }

        // `state` varchar(255) DEFAULT "C" COMMENT "单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)F已整单退货",
        if ($order_db["state"] == "B") {
            return (json(["code" => 201, "time" => time(), "msg" => "已整单结算", "query" => $query,]));
        } elseif ($order_db["state"] == "F") {
            return (json(["code" => 201, "time" => time(), "msg" => "已整单退货", "query" => $query,]));
        } else {

        }


        // 支付流水表_总在帐金额
        $pay_net_amount = Db::table("pos__p_sell_order_pay")->where(["order_dbid" => $query["dbid"]])->column("net_amount");
        $pay_net_amount = array_sum($pay_net_amount);//对数组中所有值求和

        // 验证
        if ($pay_net_amount == $order_db["total_price_new"]) {
            $apidb = ["code" => 201, "time" => time(), "msg" => "总在帐金额与应付款金额相等，但订单状态为[" . $order_db["state"] . "][481]", "query" => $query,];
            return (json($apidb));
        } else if ($pay_net_amount > $order_db["total_price_new"]) {
            $apidb = ["code" => 201, "time" => time(), "msg" => "总在帐金额大于应付款金额，但订单状态为[" . $order_db["state"] . "][481]", "query" => $query,];
            return (json($apidb));
        } else {

        }




        /** 找零金额信息 */
        $money = [
            "give_change" => 0,//本次找零
            "total_amount" => $query["total_amount"],//请求金额
            "money_in" => $query["total_amount"],//填表金额
        ];


        /** 填表金额 */
        // 客人本次支付金额(等于)整单剩余应收款--结账没找零-单头状态为完成
        // 客人本次支付金额(大于)整单剩余应收款--结账有找零-单头状态为完成
        // 客人本次支付金额(小于)整单剩余应收款--返回下次应收款-单头状态为支付中

        if ($query["total_amount"] == $order_db["total_price_new"]) {
            //刚好-不找零
        } else if ($query["total_amount"] < $order_db["total_price_new"]) {
            //给少了-不找零
        } else if ($query["total_amount"] > $order_db["total_price_new"]) {
            //给多了-要找零-[本次找零=整单应收款-本次支付金额]
            $money["give_change"] = (float) bcsub((string) $query["total_amount"], (string) $order_db["total_price_new"], 4);
            // [填表金额=整单应收款-已收款]
            $money["money_in"] = (float) bcsub((string) $order_db["total_price_new"], (string) $pay_net_amount, 4);
        } else {
        }


        if ($query["payway"] == "9") {
            // 现金支付
            if (empty($query["pay_currency"])) {
                $apidb = ["code" => 201, "msg" => "参数异常-支付币种-pay_currency", "query" => $query,];
                return (json($apidb));
            }

            // 支付币种
            $query["pay_currency"] = strtoupper($query["pay_currency"]); //转为大写
            $pay_currency_is = com_currency($query["pay_currency"]);
            if ($pay_currency_is["val"] == null) {
                $apidb = ["code" => 201, "msg" => "支付币种不支持", "query" => $query, "db" => $pay_currency_is];
                return (json($apidb));
            }
            // 当前币种数据
            $cash_db = mysql::where([
                ["order_dbid", "=", $query["dbid"]],
                ["payway", "=", "9"],
                ["pay_currency", "=", $query["pay_currency"]],
            ])->order("id", "asc")->select()->toArray();

            if (count($cash_db) > 1) {
                $apidb = ["code" => 201, "msg" => "当前币种数据异常-存在多行[560-Pay]", "query" => $query, "count" => count($cash_db)];
                return (json($apidb));
            }

            if (count($cash_db) < 1) {
                // 写现金订单
                $client_sn = "9" . time() . rand(1000, 9999); //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
                $code = 200; //状态码
                $msg = "现金支付"; //状态信息
                $sql_insert_sell_pos_order_pay = Db::name("pos__p_sell_order_pay")
                    ->strict(false)
                    ->insert([
                        "order_dbid" => $query["dbid"], //对应订单数据编号
                        "client_sn" => $client_sn, //关联支付系统的商户系统订单号_必须在商户系统内唯一
                        "payway" => "9", //支付方式_2支付宝3微信9现金8聚合支付
                        "pay_currency" => $query["pay_currency"],
                        "pay_currency_name" => $pay_currency_is["val"]["name"], //支付币种_名称
                        "pay_currency_ico" => $pay_currency_is["val"]["ico"], //支付币种_图标
                        "total_amount" => $money["money_in"], //交易金额-填表金额money_in
                        "net_amount" => $money["money_in"], //计算属性-在帐金额-实收金额减退款金额
                        "state" => "A", //单据状态
                        "x_del" => 0, //预删除
                        "time_new" => time(), //计算属性-创建时间
                        "time_up" => time(), //计算属性-修改时间
                    ]);
            } else {
                $client_sn = $cash_db[0]["client_sn"]; //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
                // 在现存现金订单-金额累加
                $sql_insert_sell_pos_order_pay2 = mysql::where([
                    "order_dbid" => $query["dbid"],
                    "client_sn" => $client_sn, //关联支付系统的商户系统订单号_必须在商户系统内唯一
                    "payway" => "9",
                    "id" => $cash_db[0]["id"],
                    "pay_currency" => $query["pay_currency"],
                ])->update([
                            "total_amount" => (float) bcadd((string) $cash_db[0]["total_amount"], (string) $money["money_in"], 4), //原始交易实收金额
                            "net_amount" => (float) bcadd((string) $cash_db[0]["net_amount"], (string) $money["money_in"], 4), //计算属性-在帐金额-实收金额减退款金额
                            "pay_currency" => $query["pay_currency"],
                            "pay_currency_name" => $pay_currency_is["val"]["name"], //支付币种_名称
                            "pay_currency_ico" => $pay_currency_is["val"]["ico"], //支付币种_图标

                            "state" => "A", //单据状态
                            "x_del" => 0, //预删除
                            "time_up" => time(), //计算属性-修改时间
                        ]);
            }
            $code = 200; //状态码
            $msg = "现金支付成功"; //状态信息


        } elseif ($query["payway"] == "8") {
            // 8在线支付
            $total_amount = $query["total_amount"] * 100; //交易金额
            $client_sn = "8" . time() . rand(1000, 9999); //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
            // 商家扫用户支付接口
            $url = "http://127.0.0.1:81/POS_V1/PaySqb/pos_pay";
            // 请求头
            $header = ["Format:json", "charset=utf-8", "Content-Type: application/json", "Authorization:sn"];
            // Pay请求数据包
            $pay_db = [
                "client_sn" => $client_sn, //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
                "total_amount" => (string) $total_amount, //交易总金额-以分为单位,不超过10位纯数字字符串,超过1亿元的收款请使用银行转账
                // "payway" => "3", //支付方式-内容为数字的字符串-2:支付宝3:微信
                "subject" => "本次交易的概述", //本次交易的概述
                "operator" => "工号1001", //发起本次交易的操作员
                "dynamic_id" => request()->param("dynamic_id", "", "trim"), //条码内容（支付包或微信条码号）
            ];
            // PAY远程HTTP
            $pay_api_notify = $this->curl_HTTP($url, $header, json_encode($pay_db));
            if (!$pay_api_notify) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构异常[554-fu_Pay_online]", "query" => $query, "db" => []];
                return $apidb;
            }
            $api_array = json_decode($pay_api_notify, true); //转数组
            // 回调验证
            if (!is_array($api_array)) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构转数组异常[594-Pay]", "query" => $query, "db" => []];
                return json($apidb);
            }
            if ($api_array["code"] != 200) {
                $apidb = ["code" => 201, "msg" => "一级接口异常[598-Pay]", "query" => $query, "db" => $api_array];
                return json($apidb);
            }
            if ($api_array["pay_db"]["result_code"] != "200") {
                $apidb = ["code" => 201, "msg" => "二级支付接口sqb异常[602-Pay]", "query" => $query, "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            if (!isset($api_array["pay_db"]["biz_response"])) {
                $apidb = ["code" => 201, "msg" => "二级支付接口异常-通讯不成功[607-Pay]", "query" => $query, "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            // 严格验证-不成功立即退出程序
            if ($api_array["pay_db"]["biz_response"]["data"]["order_status"] != "PAID") {
                // 业务执行错误码列表 ¶ https://doc.shouqianba.com/zh-cn/api/annex/resultCode.html
                $apidb = ["code" => 201, "msg" => $api_array["pay_db"]["biz_response"]["error_message"] . "-" . $api_array["pay_db"]["biz_response"]["error_code"] . "-支付订单状态异常[619-Pay]",];
                return json($apidb);
            }
            // return json($api_array["pay_db"]);
            if (isset($api_array["pay_db"]["biz_response"]["data"]["sn"])) {
                $pay_sn = $api_array["pay_db"]["biz_response"]["data"]["sn"]; //第三方支付系统返回的唯一单号
            } else {
                $pay_sn = null;
            }
            $pay_db = $pay_api_notify; //支付接口回调
            $code = 200; //状态码
            $msg = "在线支付"; //状态信息
            // POS销售单据关联支付明细
            $sql_insert_sell_pos_order_pay = Db::name("pos__p_sell_order_pay")
                ->strict(false)
                ->insert([
                    "order_dbid" => $order_db["dbid"], //对应订单数据编号
                    "client_sn" => $client_sn, //关联支付系统的商户系统订单号_必须在商户系统内唯一
                    "pay_sn" => $pay_sn, //第三方支付系统返回的唯一单号
                    "payway" => "8", //支付方式_2支付宝3微信9现金8聚合支付
                    // "state"  => $state, //单据状态_A支付成功B退款成功
                    "total_amount" => $total_amount / 100, //原始交易实收金额
                    "net_amount" => $total_amount / 100, //计算属性-在帐金额-实收金额减退款金额
                    "pay_db" => $pay_db, //支付接口回调
                    "time_new" => time(), //计算属性-创建时间
                    "time_up" => time(), //计算属性-修改时间
                ]);
            $code = 200; //状态码
            $msg = "线上支付成功"; //状态信息
        } else {
            $apidb = ["code" => 201, "msg" => "支付方式溢出", "query" => $query,];
            return (json($apidb));
        }

        // 支付流水表_总在帐金额
        $pay_net_amount = Db::table("pos__p_sell_order_pay")->where(["order_dbid" => $query["dbid"]])->column("net_amount");
        $pay_net_amount = array_sum($pay_net_amount);//对数组中所有值求和



        // 更新订单头字段
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();
        if ($pay_net_amount < $order_db["total_price_new"]) {
            # 金额未够
            $state = "E"; //单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)F已整单退货
        } else {
            # 全部支付完成
            $state = "B"; //单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)F已整单退货
        }

        Db::name("pos__p_sell_order")->where(["dbid" => $query["dbid"],])
            ->update([
                "state" => $state, //单据状态
                "time_up" => time(), //计算属性-修改时间

            ]);

        //  调用查询接口
        $PosOrderPayLi__db = $this->Query(true, $query["dbid"], $client_sn);
        $PosOrderPayLi__db = $PosOrderPayLi__db->getData();
        foreach ($PosOrderPayLi__db as $rs) {
            // unset($PosOrderPayLi__db["code"]);
            // unset($PosOrderPayLi__db["time"]);
            // unset($PosOrderPayLi__db["msg"]);
            unset($PosOrderPayLi__db["query"]);
        }
        // API接口信息
        $help = [
            "name" => "发起支付-POS支付",
            "notice" => "部分字段可能不返回，没用到的字段不要预设，部分描述文字可能有错误。",
            "txt" => "本接口会返回支付情况，并附加返回当前销售订单的相关数据，相当于支付完后查询一次查询接口",
            "code" => "错误代码",
            "time" => "接口运行时间",
            "msg" => "状态信息",
            "query=接口请求参数包" => [
                "dbid" => "销售单-单号-必填",
                "sign" => "改单签名串",
                "payway" => "支付方式_9现金8聚合支付",
                "total_amount" => "交易金额",
                "dynamic_id" => "支付码（支付宝或微信条码号-聚合支付时必填）",
                "operator" => "门店操作员",
                "remark" => "备注",
                "pay_currency" => "支付币种-云支付时无效"
            ],
            "db" => "接口回调核心数据包",
            "order_info" => "销售订单相关最新信息包"
        ];


        /** 单头 */
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();


        $apidb = [
            "code" => $code, //状态码
            "time" => time(),
            "msg" => $msg, //状态信息
            // "query" => $query, //请求参数
            "money" => $money, //找零金额信息
            "order_db" => $order_db, //最新订单信息
            // "order_info" => $PosOrderPayLi__db, //
            // "API接口信息" => $help, //API信息
        ];
        return (json($apidb));
    }

    // POS销售-退款
    public function Refund()
    {
        $query = request()->param(); //请求参数
        // 请求方式验证
        if (!request()->isPost()) {
            $apidb = ["code" => 201, "time" => time(), "msg" => "请求有误-不是POST方式!",];
            return json($apidb);
        }
        $validate = new \app\pos_v1\validate\SellPosPAY_Refund; //验证规则
        if (!$validate->check($query)) {
            // 验证不过关提示
            $apidb = ["code" => 201, "msg" => "参数异常-" . $validate->getError(), "query" => $query,];
            return json($apidb);
        }

        // 退款方式_1单项退款2整单退款
        if ($query["refund_ty"] == 2) {
            $apidb = ["code" => 201, "msg" => "整单退款权限不足[792]", "query" => $query,];
            return (json($apidb));
        }
        // 销售订单
        $order_db = Db::table("pos__p_sell_order")->where(["dbid" => $query["dbid"]])->find();
        if ($order_db == null) {
            // 数据集为空
            $apidb = ["code" => 201, "time" => time(), "msg" => "销售单不存在[800]", "query" => $query,];
            return (json($apidb));
        }
        // 当前要处理的支付订单
        $pay_db = mysql::where(["order_dbid" => $query["dbid"], "client_sn" => $query["client_sn"],])->find();
        if ($pay_db == null) {
            $apidb = ["code" => 201, "msg" => "支付订单不存在[806]", "query" => $query,];
            return (json($apidb));
        }

        if ($pay_db["payway"] == "8") {
            //   当前查到的是线上支付单
            if (empty($pay_db["pay_sn"])) {
                $apidb = ["code" => 201, "msg" => "参数异常-pay_sn[773]",];
                return (json($apidb));
            }
            if ($pay_db["pay_sn"] <> $query["refund_sn"]) {
                $apidb = ["code" => 201, "msg" => "参数异常-refund_sn[776]",];
                return (json($apidb));
            }

            // state单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
            if ($pay_db["state"] == "ES") {
                $apidb = ["code" => 201, "msg" => "订单异常状态[778]",];
                return (json($apidb));
            }
            if ($pay_db["state"] == "B1") {
                $apidb = ["code" => 201, "msg" => "已全部退款[782]",];
                return (json($apidb));
            }
            if ($pay_db["state"] == "B3") {
                $apidb = ["code" => 201, "msg" => "退款进行中[786]",];
                return (json($apidb));
            }
            if ($pay_db["net_amount"] <= 0) {
                $apidb = ["code" => 201, "msg" => "无可退金额[791]", "pay_db" => $pay_db];
                return (json($apidb));
            }
            // 退款接口
            $url = "http://127.0.0.1:81/POS_V1/PaySqb/pos_refund";

            // 请求头
            $header = ["Format:json", "charset=utf-8", "Content-Type: application/json", "Authorization:sn"];
            // Pay请求数据包
            // sn与client_sn不能同时为空，优先按照sn查找订单，如果没有，再按照client_sn查询
            $pay_api_db = [
                "pay_sn" => $pay_db["pay_sn"], //收钱吧系统内部唯一订单号 sn与client_sn不能同时为空，优先按照sn查找订单，如果没有，再按照client_sn查询
                "client_sn" => $pay_db["client_sn"], //商户系统订单号,必须在商户系统内唯一；且长度不超过32字节
                "refund_amount" => $pay_db["net_amount"] * 100, //退款金额
                "operator" => $query["operator"], //门店操作员
            ];
            // PAY远程HTTP
            $pay_api_notify = $this->curl_HTTP($url, $header, json_encode($pay_api_db));
            if (!$pay_api_notify) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构异常[752-fu_Pay_online]", "query" => request()->param(), "db" => []];
                return $apidb;
            }
            $api_array = json_decode($pay_api_notify, true); //转数组
            // 回调验证
            if (!is_array($api_array)) {
                $apidb = ["code" => 201, "msg" => "接口回调数据结构转数组异常[817]", "db" => []];
                return json($apidb);
            }
            if ($api_array["code"] != 200) {
                $apidb = ["code" => 201, "msg" => "一级接口异常[821]", "db" => $api_array];
                return json($apidb);
            }
            if ($api_array["pay_db"]["result_code"] != "200") {
                $apidb = ["code" => 201, "msg" => "二级支付接口sqb异常[829]" . $api_array["pay_db"]["error_message"], "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            if (!isset($api_array["pay_db"]["biz_response"])) {
                $apidb = ["code" => 201, "msg" => "二级支付接口异常-通讯不成功[833]", "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            if ($api_array["pay_db"]["biz_response"]["result_code"] == "FAIL") {
                $apidb = ["code" => 201, "msg" => "业务操作失败[839]" . $api_array["pay_db"]["biz_response"]["error_message"], "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            if (!isset($api_array["pay_db"]["biz_response"]["data"])) {
                $apidb = ["code" => 201, "msg" => "二级支付接口数据包异常[843]", "db" => $api_array["pay_db"]];
                return json($apidb);
            }
            // 严格验证-不成功立即退出程序
            if ($api_array["pay_db"]["biz_response"]["data"]["status"] != "SUCCESS") {
                // 业务执行错误码列表 ¶ https://doc.shouqianba.com/zh-cn/api/annex/resultCode.html
                $apidb = ["code" => 201, "msg" => "退款异常[849]" . $api_array["pay_db"]["biz_response"]["error_message"] . "-" . $api_array["pay_db"]["biz_response"]["error_code"],];
                return json($apidb);
            }
            // 订单状态列表 ¶
            // https://doc.shouqianba.com/zh-cn/api/annex/resultCode.html
            // biz_response.data.order_status
            // 取值	含义
            // CREATED	订单已创建/支付中
            // PAID	订单支付成功
            // PAY_CANCELED	支付失败并且已经成功充正
            // PAY_ERROR	支付异常，不确定是否已经成功充正,请联系收钱吧客服确认是否支付成功
            // REFUNDED	已成功全额退款
            // PARTIAL_REFUNDED	已成功部分退款
            // REFUND_INPROGRESS	退款进行中
            // REFUND_ERROR	退款异常并且不确定第三方支付通道的最终退款状态
            // CANCELED	客户端发起的撤单已成功
            // CANCEL_ERROR	客户端发起的撤单异常并且不确定第三方支付通道的最终状态
            // CANCEL_INPROGRESS	撤单进行中
            // INVALID_STATUS_CODE	无效的状态码
            // 开发者根据返回的biz_response.data.order_status 属性判断当前收钱吧订单的状态。
            $order_status = $api_array["pay_db"]["biz_response"]["data"]["order_status"];
            if ($order_status == "REFUNDED") {
                $code = 200;
                $msg = "已成功全额退款[873]";
            } else if ($order_status == "PARTIAL_REFUNDED") {
                $code = 200;
                $msg = "已成功部分退款[875]";
            } else if ($order_status == "REFUND_INPROGRESS") {
                $code = 201;
                $msg = "退款进行中[878]";
            } else if ($order_status == "REFUND_ERROR") {
                $code = 201;
                $msg = "退款异常并且不确定第三方支付通道的最终退款状态[882]";
            } else if ($order_status == "INVALID_STATUS_CODE") {
                $code = 201;
                $msg = "无效的状态码[885]";
            } else {
                $code = 201;
                $msg = "在线退款执行例程溢出[887]";
            }
            // 修改之前查询到的支付单
            $pay_db->state = "B1"; //单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
            // $pay_db->total_amount = 0; //计算属性-原始交易实收金额[退款时不改-付款时改]
            $pay_db->net_amount = $api_array["pay_db"]["biz_response"]["data"]["net_amount"] / 100; //计算属性-在帐金额-实收金额减退款金额
            $pay_db->time_up = time(); //修改时间
            $pay_db2 = $pay_db->save();
            $apidb = [
                "code" => $code,
                "time" => time(),
                "msg" => $msg,
                // "query" => $query,
                // "db" => $api_array["pay_db"],
            ];
            return (json($apidb));
        } else if ($pay_db["payway"] == "9") {
            //当前查到的是现金支付单
            if ($pay_db["net_amount"] == 0) {
                $apidb = ["code" => 201, "time" => time(), "msg" => "无可用退款金额", "query" => $query,];
                return (json($apidb));
            }
            // 修改之前查询到的支付单
            $pay_db->state = "B1"; //单据状态_ES异常状态A支付成功B1全额退款B2部分退款B3退款进行中
            // $pay_db->total_amount = 0; //计算属性-原始交易实收金额[退款时不改-付款时改]
            $pay_db->net_amount = 0; //计算属性-在帐金额-实收金额减退款金额
            $pay_db->time_up = time(); //修改时间
            $pay_db2 = $pay_db->save();
            if ($pay_db2 == true) {
                $code = 200;
                $msg = "退款成功[918]";
            } else {
                $code = 201;
                $msg = "退款失败[921]";
            }
            $apidb = [
                "code" => $code,
                "time" => time(),
                "msg" => $msg,
                // "query" => $query,
                "db" => $pay_db,
            ];
            return (json($apidb));
        } else {
        }
    }

}
